﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace ACC.Extensions.ClientBusiness
{
    /// <summary>
    /// Socket Client
    /// </summary>
    public class SocketClient
    {
        private Socket _clientSocket;
        private string _IPAddress;   // 服务器端ip
        private int _Port;                // 服务器端口
        private Thread _recvThread;
        private Thread _heartBeatThread;
        private bool isConnected;
        public bool IsConnected { get { return isConnected; } }   // 标识当前是否连接到服务器
        public string SocketName { get; set; }

        public delegate void PrintEventHandler(string strData, string strMsg, bool isWaring); // Print用于输出Server的输出信息
        private PrintEventHandler _OnPrint; 
        public delegate void ConnectedHandler(string strDeviceName, bool bIsConnected);
        public event ConnectedHandler OnConnected;
        public SocketClient(PrintEventHandler print, string ipString, int port)
        {
            this._OnPrint = print;
            if (!string.IsNullOrEmpty(ipString)) this._IPAddress = ipString;
            if (port >= 0) this._Port = port;
        }

        public SocketClient(PrintEventHandler print, string ipString, string port)
        {
            this._OnPrint = print;
            if (ipString != null) this._IPAddress = ipString;

            int port_int = Int32.Parse(port);
            if (port_int >= 0) this._Port = port_int;
        }


        /// <summary>
        /// 启动客户端，连接至服务器
        /// </summary>
        public void Start()
        {
            //启动发送心跳的线程
            _heartBeatThread = new Thread(HeartBeatLoop);
            _heartBeatThread.IsBackground = true;
            _heartBeatThread.Start();

            _recvThread = new Thread(ReceiveData);
            _recvThread.IsBackground = true;
            _recvThread.Start();      // 在新的线程中接收服务器信息

        }

        /// <summary>
        /// 结束客户端
        /// </summary>
        public void Stop()
        {
            isConnected = false;

            if (_heartBeatThread != null && _heartBeatThread.ThreadState == ThreadState.Running)
            {
                _heartBeatThread.Join(5000);
            }
            if (_recvThread != null && _recvThread.ThreadState == ThreadState.Running)
            {
                _recvThread.Join(5000);
            }
            _heartBeatThread = null;
            _recvThread = null;
            if (OnConnected != null) OnConnected(SocketName, IsConnected);
            if(_clientSocket!=null)
            {
                _clientSocket.Close();
                _clientSocket.Dispose();
            }
        }

        private void HeartBeatLoop()
        {
            while (true)
            {
                try
                {
                    IPAddress ip = IPAddress.Parse(_IPAddress);
                    if (_clientSocket == null)
                    {
                        _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        _clientSocket.SendTimeout = 5000; //设置超时
                        _clientSocket.Connect(new IPEndPoint(ip, _Port));   // 连接服务器
                        if (_OnPrint != null) _OnPrint("", "连接服务器【" + _clientSocket.RemoteEndPoint.ToString() + "】完成", false); // 连接成功
                    
                    }
                    else
                    {
                        if (!_clientSocket.Connected)
                        {
                            _clientSocket.Close();
                            _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                            _clientSocket.SendTimeout = 5000; //设置超时
                            _clientSocket.Connect(new IPEndPoint(ip, _Port));   // 连接服务器
                            if (_OnPrint != null) _OnPrint("", "连接服务器【" + _clientSocket.RemoteEndPoint.ToString() + "】完成", false); // 连接成功
                    
                        }
                        else
                        {
                            _clientSocket.Send(Encoding.Unicode.GetBytes("test connect"));
                            //string recvStr = "";
                            //byte[] recvBytes = new byte[1024];
                            //int bytes = _clientSocket.Receive(recvBytes, recvBytes.Length, 0);//从服务器端接受返回信息
                            //recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);
                            isConnected = true;
                            if (OnConnected != null) OnConnected(SocketName, IsConnected);
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (_OnPrint != null) _OnPrint("", "连接服务器失败 " + ex.Message.ToString(), true);
                    isConnected = false;
                    if (OnConnected != null) OnConnected(SocketName, IsConnected);
                }

                Thread.Sleep(5000);
            }
        }
        /// <summary>
        /// 发送信息
        /// </summary>
        public void Send(string info)
        {
            try
            {
                Send(_clientSocket, info);
            }
            catch (Exception ex)
            {
                if (_OnPrint != null) _OnPrint("", "服务器端已断开，【" + _clientSocket.RemoteEndPoint.ToString() + "】", true);
            }
        }

        /// <summary>
        /// 通过socket发送数据data
        /// </summary>
        private void Send(Socket socket, string data)
        {
            if (socket != null && data != null && !data.Equals(""))
            {
                byte[] bytes = Encoding.UTF8.GetBytes(data);   // 将data转化为byte数组
                socket.Send(bytes);
            }
        }

        /// <summary>
        /// 接收通过socket发送过来的数据
        /// </summary>
        private void ReceiveData()
        {
            while (true)
            {
                if (IsConnected == false)
                {
                    Thread.Sleep(2000);
                }
                try
                {
                    string data = Receive(_clientSocket);     // 接收客户端发送的信息
                    if (!data.Equals(""))
                    {
                        if (_OnPrint != null) _OnPrint(data, "服务器" + _clientSocket.RemoteEndPoint.ToString() + "信息：\r\n" + data, false);
                        if (data.Equals("[.Shutdown]")) System.Environment.Exit(0);
                    }
                }
                catch (Exception ex)
                {
                    if (_OnPrint != null) _OnPrint("", "连接已自动断开，" + ex.Message, true);
                 
                    isConnected = false;
                    if (OnConnected != null) OnConnected(SocketName, IsConnected);
                }
                Thread.Sleep(200);      // 延时0.2后处理接收到的信息
            }
        }
        /// <summary>
        /// 从socket接收数据
        /// </summary>
        private string Receive(Socket socket)
        {
            string data = "";

            byte[] bytes = null;
            int len = socket.Available;
            if (len > 0)
            {
                bytes = new byte[len];
                int receiveNumber = socket.Receive(bytes);
                data = Encoding.UTF8.GetString(bytes, 0, receiveNumber);
            }

            return data;
        }

       

    }
}
